﻿using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;
using Serilog.Events;
using ThridGroup.ERP.HumanResources;
using ThridGroup.ERP.ProductionSystem;
using ThridGroup.ERP.RBAC;
using ThridGroup.ERP.Application.ProductionSystem;
using ThridGroup.ERP.ProductionSystem.ShiftSchedulingManagement;
using System.Threading.Tasks;
using System;
using ThridGroup.ERP.Application.Contracts.ProductionSystem;
using ThridGroup.ERP.WarehouseManagement;
using Microsoft.EntityFrameworkCore;
using Polly;
using Microsoft.AspNetCore.Hosting;

namespace ThridGroup.ERP.Web;

public class Program
{
    
    public async static Task<int> Main(string[] args)
    {
        AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
        AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);

        Log.Logger = new LoggerConfiguration()
            .WriteTo.Async(c => c.File("Logs/logs.txt"))
            .WriteTo.Async(c => c.Console())
            .CreateBootstrapLogger();
        try
        {
            Log.Information("Starting web host.");
            var builder = WebApplication.CreateBuilder(args);

            // 添加Kestrel服务器配置，尝试指定端口，如果被占用则自动获取可用端口
            builder.WebHost.ConfigureKestrel(serverOptions =>
            {
                // 禁用默认的HTTPS证书验证以解决开发环境的证书问题
                serverOptions.ConfigureHttpsDefaults(options =>
                {
                    options.SslProtocols = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls13;
                    // 开发环境中禁用证书验证
                    options.ClientCertificateMode = Microsoft.AspNetCore.Server.Kestrel.Https.ClientCertificateMode.NoCertificate;
                    options.AllowAnyClientCertificate();
                    // 禁用证书验证
                    options.ServerCertificate = null;
                    options.CheckCertificateRevocation = false;
                });
                
                // 在5000端口上监听HTTP
                serverOptions.ListenLocalhost(5000, listenOptions =>
                {
                    listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http1AndHttp2;
                });
                
                // 在5001端口上监听HTTPS
                serverOptions.ListenLocalhost(5001, listenOptions =>
                {
                    listenOptions.UseHttps(httpsOptions =>
                    {
                        httpsOptions.SslProtocols = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls13;
                        httpsOptions.ClientCertificateMode = Microsoft.AspNetCore.Server.Kestrel.Https.ClientCertificateMode.NoCertificate;
                        httpsOptions.CheckCertificateRevocation = false;
                    });
                    listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http1AndHttp2;
                });
            });

            // 设置应用URL支持HTTP和HTTPS
            builder.WebHost.UseUrls("http://localhost:5000;https://localhost:5001");

            builder.Services.AddTransient<UserIServices, UserServices>();

            // 注册角色服务
            builder.Services.AddTransient<ThridGroup.ERP.RBAC.IRoleServicers, ThridGroup.ERP.RBAC.RoleServices>();
            // 注册权限服务
            builder.Services.AddTransient<IPermissionServices, PermissionServices>();
          
            builder.Services.AddTransient<ThridGroup.ERP.RBAC.IRolePermissionServices, ThridGroup.ERP.RBAC.RolePermissionServices>();//角色权限
            builder.Services.AddTransient<IAddOnboardingReviewServices, AddOnboardingReviewServices>();
            builder.Services.AddTransient<ThridGroup.ERP.ProductionSystem.EquipmentTypeIService, ThridGroup.ERP.ProductionSystem.EquipmentTypeService>();
            //职位管理服务
            builder.Services.AddTransient<IPositionManagementServices, JobGradeManagementServices>();
            //物料信息服务
            builder.Services.AddTransient<IMaterielServices, MaterielServices>();

            
            // 注册物料分类服务
            builder.Services.AddTransient<IMaterialTypeService, MaterialTypeService>();
            
            // 注册车间服务
            builder.Services.AddTransient<IWorkshopService, WorkshopService>();
            // 注册生产退料
            builder.Services.AddTransient<IProductionMaterialReturnServices, ProductionMaterialReturnServices>();
            
            // 注册生产领料服务
            builder.Services.AddTransient<IProductionMaterialServices, ProductionMaterialServices>();

            // 注册班组管理服务
            builder.Services.AddTransient<ITeamServices, TeamServices>();
            
            // 注册采购入库服务
            builder.Services.AddTransient<IProcurementServices, ProcurementServices>();
            
            // 注册产品入库服务
            builder.Services.AddTransient<ThridGroup.ERP.WarehouseManagement.IProductsInboundServices, ThridGroup.ERP.WarehouseManagement.ProductsInboundServices>();

            // 注册仓库设置服务
            builder.Services.AddTransient<ThridGroup.ERP.WarehouseManagement.IWarehouseSettingService, ThridGroup.ERP.Application.WarehouseManagement.WarehouseSettingService>();
            
            // 注册库区设置服务
            builder.Services.AddTransient<ThridGroup.ERP.WarehouseManagement.IWarehouseAreaSettingService, ThridGroup.ERP.Application.WarehouseManagement.WarehouseAreaSettingService>();
            
            // 注册销售出库服务
            builder.Services.AddTransient<SaleIService, SaleService>();

            // 注册赋码管理服务
            builder.Services.AddTransient<ThridGroup.ERP.WarehouseManagement.ICodingmanagementService, ThridGroup.ERP.Application.WarehouseManagement.CodingmanagementService>();

            // 注册销售订单服务
            builder.Services.AddTransient<ThridGroup.ERP.Application.Contracts.OrderManagement.ISalesOrderService, ThridGroup.ERP.Application.OrderManagement.SalesOrderService>();

            // 配置JSON序列化选项
            builder.Services.ConfigureHttpJsonOptions(options =>
            {
                options.SerializerOptions.PropertyNameCaseInsensitive = true;
                options.SerializerOptions.PropertyNamingPolicy = null; // 保持PascalCase
            });
            builder.Services.AddTransient<IAddOnboardingReviewServices, AddOnboardingReviewServices>();
            builder.Services.AddTransient<ICustomerServices, CustomerServices>();
            builder.Services.AddTransient<IProductionServices, ProductionServices>();

            //检测项设置
           builder.Services.AddTransient<IItemSettingsServices, ItemSettingsServices>();
            //排班计划
            builder.Services.AddTransient<ICrewSchedulingServices, CrewSchedulingServices>();
            //供应商退货
            builder.Services.AddTransient<ISupplierReturnsServices, SupplierReturnsServices>();
            //库存盘点
            builder.Services.AddTransient<IInventoryCountsServices, InventoryCountsServices>();
            //库存废料
            builder.Services.AddTransient<IProductionWasteOrderServices, ProductionWasteOrderServices>();
            
            // 注册节假日设置服务
            builder.Services.AddTransient<Three.BookStore.ProductionSystem.ShiftManagement.IHolidaySettingServices, Three.BookStore.ProductionSystem.ShiftManagement.HolidaySettingServices>();

            
            // 注册转移调拨服务
            builder.Services.AddTransient<ITransferTransfersServices, TransferTransfersServices>();
            // 配置 CORS
            builder.Services.AddCors(options =>
            {
                options.AddDefaultPolicy(builder =>
                {
                    builder.WithOrigins("https://localhost:44384")
                           .AllowAnyMethod()
                           .AllowAnyHeader()
                           .AllowCredentials();
                });
            });
            
            //注册面试服务
            builder.Services.AddTransient<InterviewIService, InterviewService>();
            // 注册设备类型服务
            builder.Services.AddTransient<ThridGroup.ERP.ProductionSystem.EquipmentTypeIService, ThridGroup.ERP.ProductionSystem.EquipmentTypeService>();
            builder.Host
                .AddAppSettingsSecretsJson()
                .UseAutofac()
                .UseSerilog((context, services, loggerConfiguration) =>
                {
                    loggerConfiguration
                    #if DEBUG
                        .MinimumLevel.Debug()
                    #else
                        .MinimumLevel.Information()
                    #endif
                        .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
                        .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning)
                        .Enrich.FromLogContext()
                        .WriteTo.Async(c => c.File("Logs/logs.txt"))
                        .WriteTo.Async(c => c.Console())
                        .WriteTo.Async(c => c.AbpStudio(services));
                });
            await builder.AddApplicationAsync<ERPWebModule>();
            var app = builder.Build();
            await app.InitializeApplicationAsync();

            // 启用 CORS
            app.UseCors();

            // 配置静态文件
            app.UseStaticFiles(new StaticFileOptions
            {
                ServeUnknownFileTypes = true,
                DefaultContentType = "application/octet-stream"
            });

            // 配置路由
            app.UseRouting();
            app.UseEndpoints(endpoints =>
            {
                // 启用特性路由
                endpoints.MapControllers();
                
                // 默认路由
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
                
                // 根路由重定向
                endpoints.MapGet("/", context =>
                {
                    context.Response.Redirect("/Home/Index");
                    return Task.CompletedTask;
                });
                    
                endpoints.MapRazorPages();
            });

            // 启动应用程序并等待它运行
            var runTask = app.RunAsync();
            
            // 输出启动成功信息
            Log.Information("Application started successfully. Press Ctrl+C to shut down.");
            
            // 在控制台应用中，添加一个等待用户输入的提示，防止程序自动退出
            if (Environment.UserInteractive && !Console.IsInputRedirected)
            {
                Console.WriteLine("Application is running. Press Enter to stop...");
                // 等待用户按下回车键
                Console.ReadLine();
                // 如果用户按下回车键，则正常退出
                return 0;
            }
            else
            {
                // 在非交互式环境中，等待应用程序运行结束
                await runTask;
                return 0;
            }
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Host terminated unexpectedly!");
            return 1;
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }
}
